package com.b.controller;

import com.b.domain.Admin;
import com.b.repository.AdminRepository;
import com.b.service.AdminService;
import com.b.utils.JwtUtil;
import com.b.utils.MD5Util;
import com.b.vo.Result;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * 管理员表(admin)表控制层
 *
 * @author xxxxx
 */
@RestController
@CrossOrigin
@RequestMapping("/admin")
public class AdminController {
    /**
     * 服务对象
     */
    @Resource
    private AdminService adminService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;


    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("selectOne")
    public Admin selectOne(Integer id) {
        return adminService.selectByPrimaryKey(id);
    }

    @RequestMapping("login")
    public Result login(@RequestBody Admin admin) {
        String username = admin.getUsername();
        String inputPasswordHash = MD5Util.code(admin.getPasswordHash());
        Admin admin1 = adminService.findByUsername(username);
        if (admin1 == null){
            return new Result().setCode("400").setMsg("用户不存在");
        } else {
            // 使用常量时间比较避免时序攻击，提高安全性
            if (equalsConstantTime(admin1.getPasswordHash(), inputPasswordHash)) {
                ConcurrentHashMap<String, Object> map = new ConcurrentHashMap<>();
                map.put("admin", admin1);
                String token = JwtUtil.createJWT(map);
                ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
                ops.set("admin:" + admin1.getId(), token, 30, TimeUnit.MINUTES);
                return new Result().setCode("200").setMsg("登录成功").setData(token);
            } else {
                return new Result().setCode("400").setMsg("密码错误");
            }
        }
    }

    // 使用常量时间字符串比较，防止通过响应时间差判断密码匹配情况
    private boolean equalsConstantTime(String s1, String s2) {
        if (s1 == null || s2 == null) {
            return false;
        }
        if (s1.length() != s2.length()) {
            return false;
        }
        int result = 0;
        for (int i = 0; i < s1.length(); i++) {
            result |= s1.charAt(i) ^ s2.charAt(i);
        }
        return result == 0;
    }
    /*创建admin账户*/
    @RequestMapping("create")
    public Result create(@RequestBody Admin admin) {
        return new Result().setCode("200").setMsg("创建成功").setData(adminService.insertSelective(admin));
    }
}
